home *** CD-ROM | disk | FTP | other *** search
/ Day Cry / Day Cry CD.bin / oh_towns / taropyon / splib / splib.lzh / PRG / ZMODEM / ZM.C < prev    next >
C/C++ Source or Header  |  1993-08-11  |  21KB  |  995 lines

  1. /*
  2.  * Z M . C ZMODEM protocol primitives 05-24-89    Chuck Forsberg Omen
  3.  * Technology Inc
  4.  *
  5.  * Entry point Functions: zsbhdr(type, hdr) send binary header zshhdr(type, hdr)
  6.  * send hex header zgethdr(hdr, eflag) receive header - binary or hex
  7.  * zsdata(buf, len, frameend) send data zrdata(buf, len) receive data
  8.  * stohdr(pos) store position data in Txhdr long rclhdr(hdr) recover position
  9.  * offset from header
  10.  *
  11.  *
  12.  * This version implements numerous enhancements including ZMODEM Run Length
  13.  * Encoding and variable length headers.  These features were not funded by
  14.  * the original Telenet development contract.
  15.  *
  16.  * This software may be freely used for non commercial and educational (didactic
  17.  * only) purposes.    This software may also be freely used to support file
  18.  * transfer operations to or from licensed Omen Technology products.  Any
  19.  * programs which use part or all of this software must be provided in source
  20.  * form with this notice intact except by written permission from Omen
  21.  * Technology Incorporated.
  22.  *
  23.  * Use of this software for commercial or administrative purposes except when
  24.  * exclusively limited to interfacing Omen Technology products requires a per
  25.  * port license payment of $20.00 US per port (less in quantity).  Use of
  26.  * this code by inclusion, decompilation, reverse engineering or any other
  27.  * means constitutes agreement to these conditions and acceptance of
  28.  * liability to license the materials and payment of reasonable legal costs
  29.  * necessary to enforce this license agreement.
  30.  *
  31.  *
  32.  * Omen Technology Inc            FAX: 503-621-3745 Post Office Box 4681
  33.  * Portland OR 97208
  34.  *
  35.  * This code is made available in the hope it will be useful, BUT WITHOUT ANY
  36.  * WARRANTY OF ANY KIND OR LIABILITY FOR ANY DAMAGES OF ANY KIND.
  37.  *
  38.  */
  39.  
  40. #ifndef CANFDX
  41. #include "zmodem.h"
  42. int         Rxtimeout = 100;    /* Tenths of seconds to wait for something */
  43. #endif
  44.  
  45. #ifndef UNSL
  46. #define UNSL
  47. #endif
  48.  
  49.  
  50. /* Globals used by ZMODEM functions */
  51. int         Rxframeind;         /* ZBIN ZBIN32, or ZHEX type of frame */
  52. int         Rxtype;             /* Type of header received */
  53. int         Rxhlen;             /* Length of header received */
  54. int         Rxcount;            /* Count of data bytes received */
  55. char        Rxhdr[ZMAXHLEN];    /* Received header */
  56. char        Txhdr[ZMAXHLEN];    /* Transmitted header */
  57. long        Rxpos;                /* Received file position */
  58. long        Txpos;                /* Transmitted file position */
  59. int         Txfcs32;            /* TURE means send binary frames with 32 bit
  60.                                  * FCS */
  61. int         Crc32t;             /* Controls 32 bit CRC being sent */
  62.                                 /* 1 == CRC32,    2 == CRC32 + RLE */
  63. int         Crc32r;             /* Indicates/controls 32 bit CRC being received */
  64.                                 /* 0 == CRC16,    1 == CRC32,  2 == CRC32 + RLE */
  65. int         Usevhdrs;            /* Use variable length headers */
  66. int         Znulls;             /* Number of nulls to send at beginning of
  67.                                  * ZDATA hdr */
  68. char        Attn[ZATTNLEN + 1]; /* Attention string rx sends to tx on err */
  69. char       *Altcan;             /* Alternate canit string */
  70.  
  71. static        lastsent;            /* Last char we sent */
  72. static        Not8bit;            /* Seven bits seen on header */
  73.  
  74. static char *frametypes[] =
  75. {
  76.     "No Response to Error Correction Request",    /* -4 */
  77.     "No Carrier Detect",        /* -3 */
  78.     "TIMEOUT",                    /* -2 */
  79.     "ERROR",                    /* -1 */
  80. #define FTOFFSET 4
  81.     "ZRQINIT",
  82.     "ZRINIT",
  83.     "ZSINIT",
  84.     "ZACK",
  85.     "ZFILE",
  86.     "ZSKIP",
  87.     "ZNAK",
  88.     "ZABORT",
  89.     "ZFIN",
  90.     "ZRPOS",
  91.     "ZDATA",
  92.     "ZEOF",
  93.     "ZFERR",
  94.     "ZCRC",
  95.     "ZCHALLENGE",
  96.     "ZCOMPL",
  97.     "ZCAN",
  98.     "ZFREECNT",
  99.     "ZCOMMAND",
  100.     "ZSTDERR",
  101.     "xxxxx"
  102. #define FRTYPES 22                /* Total number of frame types in this array */
  103. /* not including psuedo negative entries */
  104. };
  105.  
  106. static char badcrc[] = "Bad CRC";
  107.  
  108. /* Send ZMODEM binary header hdr of type type */
  109. void    zsbhdr(int len, int type, register char *hdr)
  110. {
  111.     register int n;
  112.     register unsigned short crc;
  113.  
  114. #ifndef DSZ
  115.     vfile("zsbhdr: %c %d %s %lx", Usevhdrs ? 'v' : 'f', len,
  116.           frametypes[type + FTOFFSET], rclhdr(hdr));
  117. #endif
  118.     if (type == ZDATA)
  119.     {
  120.         for (n = Znulls; --n >= 0;)
  121.             xsendline(0);
  122.     }
  123.  
  124.     xsendline(ZPAD);
  125.     xsendline(ZDLE);
  126.  
  127.     switch ( Crc32t = Txfcs32 )
  128.     {
  129.         case 2:
  130.             zsbh32(len, hdr, type, Usevhdrs ? ZVBINR32 : ZBINR32);
  131.             flushmo();
  132.             break;
  133.         case 1:
  134.             zsbh32(len, hdr, type, Usevhdrs ? ZVBIN32 : ZBIN32);
  135.             break;
  136.         default:
  137.             if (Usevhdrs)
  138.             {
  139.                 xsendline(ZVBIN);
  140.                 zsendline(len);
  141.             } else
  142.                 xsendline(ZBIN);
  143.             zsendline(type);
  144.             crc = updcrc(type, 0);
  145.  
  146.             for (n = len; --n >= 0; ++hdr)
  147.             {
  148.                 zsendline( (*hdr) & 0xFF );
  149.                 crc = updcrc((0377 & *hdr), crc);
  150.             }
  151.             crc = updcrc(0, updcrc(0, crc));
  152.             zsendline(crc >> 8);
  153.             zsendline(crc);
  154.     }
  155.     if (type != ZDATA)
  156.         flushmo();
  157. }
  158.  
  159.  
  160. /* Send ZMODEM binary header hdr of type type */
  161. void    zsbh32(int len, register char *hdr, int type, int flavour)
  162. {
  163.     register int n;
  164.     register UNSL long crc;
  165.  
  166.     xsendline(flavour);
  167.     if (Usevhdrs)
  168.         zsendline(len);
  169.     zsendline(type);
  170.     crc = 0xFFFF_FFFFL;
  171.     crc = UPDC32(type, crc);
  172.  
  173.     for (n = len; --n >= 0; ++hdr)
  174.     {
  175.         crc = UPDC32((0377 & *hdr), crc);
  176.         zsendline( (*hdr) & 0xFF );
  177.     }
  178.     crc = ~crc;
  179.     for (n = 4; --n >= 0;)
  180.     {
  181.         zsendline((int) crc);
  182.         crc >>= 8;
  183.     }
  184. }
  185.  
  186. /* Send ZMODEM HEX header hdr of type type */
  187. void    zshhdr(int len, int type, register char *hdr)
  188. {
  189.     register int n;
  190.     register unsigned short crc;
  191.  
  192. #ifndef DSZ
  193.     vfile("zshhdr: %c %d %s %lx", Usevhdrs ? 'v' : 'f', len,
  194.           frametypes[type + FTOFFSET], rclhdr(hdr));
  195. #endif
  196.     sendline(ZPAD);
  197.     sendline(ZPAD);
  198.     sendline(ZDLE);
  199.     if (Usevhdrs)
  200.     {
  201.         sendline(ZVHEX);
  202.         zputhex(len);
  203.     } else
  204.         sendline(ZHEX);
  205.     zputhex(type);
  206.     Crc32t = 0;
  207.  
  208.     crc = updcrc(type, 0);
  209.     for (n = len; --n >= 0; ++hdr)
  210.     {
  211.         zputhex(*hdr);
  212.         crc = updcrc((0377 & *hdr), crc);
  213.     }
  214.     crc = updcrc(0, updcrc(0, crc));
  215.     zputhex(crc >> 8);
  216.     zputhex(crc);
  217.  
  218.     /* Make it printable on remote machine */
  219.     sendline(015);
  220.     sendline(0212);
  221.     /*
  222.      * Uncork the remote in case a fake XOFF has stopped data flow
  223.      */
  224.     if (type != ZFIN && type != ZACK)
  225.         sendline(021);
  226.     flushmo();
  227. }
  228.  
  229. /*
  230.  * Send binary array buf of length length, with ending ZDLE sequence frameend
  231.  */
  232. static char *Zendnames[] = {"ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"};
  233. void    zsdata(register char *buf, int length, int frameend)
  234. {
  235.     register unsigned short crc;
  236.  
  237. #ifndef DSZ
  238.     vfile("zsdata: %d %s", length, Zendnames[frameend - ZCRCE & 3]);
  239. #endif
  240. #ifdef    DEBUG
  241.     USR_fprintf(stderr,"zsdata: Crc32t = %d\n", Crc32t );
  242. #endif
  243.     switch (Crc32t)
  244.     {
  245.         case 1:
  246.             zsda32(buf, length, frameend);
  247.             break;
  248.         case 2:
  249.             zsdar32(buf, length, frameend);
  250.             break;
  251.         default:
  252.             crc = 0;
  253.             for (; --length >= 0; ++buf)
  254.             {
  255.                 zsendline( (*buf)&0xFF );
  256.                 crc = updcrc((0377 & *buf), crc);
  257.             }
  258.             xsendline(ZDLE);
  259.             xsendline(frameend);
  260.             crc = updcrc(frameend, crc);
  261.  
  262.             crc = updcrc(0, updcrc(0, crc));
  263.             zsendline(crc >> 8);
  264.             zsendline(crc);
  265.     }
  266.     if (frameend == ZCRCW)
  267.         xsendline(XON);
  268.     if (frameend != ZCRCG)
  269.         flushmo();
  270. }
  271.  
  272. void    zsda32(register char *buf, int length, int frameend)
  273. {
  274.     register int c;
  275.     register UNSL long crc;
  276.  
  277.     crc = 0xFFFFFFFFL;
  278.     for (; --length >= 0; ++buf)
  279.     {
  280.         c = (*buf) & 0377;
  281.         if (c & 0140)
  282.             xsendline(lastsent = c);
  283.         else
  284.             zsendline(c);
  285.         crc = UPDC32(c, crc);
  286.     }
  287.     xsendline(ZDLE);
  288.     xsendline(frameend);
  289.     crc = UPDC32(frameend, crc);
  290.  
  291.     crc = ~crc;
  292.     for (c = 4; --c >= 0;)
  293.     {
  294.         zsendline((int) crc);
  295.         crc >>= 8;
  296.     }
  297. }
  298.  
  299. /*
  300.  * Receive array buf of max length with ending ZDLE sequence and CRC.
  301.  * Returns the ending character or error code. NB: On errors may store
  302.  * length+1 bytes!
  303.  */
  304. int        zrdata(register char *buf, int length)
  305. {
  306.     register int c;
  307.     register unsigned short crc;
  308.     register char *end;
  309.     register int d;
  310.  
  311.     switch (Crc32r)
  312.     {
  313.         case 1:
  314.             return zrdat32(buf, length);
  315.         case 2:
  316.             return zrdatr32(buf, length);
  317.     }
  318.  
  319.     crc = Rxcount = 0;
  320.     end = buf + length;
  321.     while (buf <= end)
  322.     {
  323.         if ((c = zdlread()) & ~0377)
  324.         {
  325.           crcfoo:
  326.             switch (c)
  327.             {
  328.                 case GOTCRCE:
  329.                 case GOTCRCG:
  330.                 case GOTCRCQ:
  331.                 case GOTCRCW:
  332.                     crc = updcrc((d = c) & 0377, crc);
  333.                     if ((c = zdlread()) & ~0377)
  334.                         goto cr